package com.n.passwordbook.SettingsWindow;

import com.n.passwordbook.MainWindow.MainWindow;
import com.n.passwordbook.PasswordBook.PasswordBook;
import com.n.passwordbook.Utils.Helper;
import com.n.passwordbook.Utils.OperationManager;
import com.n.passwordbook.Utils.Settings;
import com.n.passwordbook.Utils.WindowHelper;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

public class SettingsWindow implements Initializable
{
    private static Stage Window;

    @FXML
    public TextField tb_oldPassword;
    @FXML
    public TextField tb_newPassword;
    @FXML
    public Text txt_oldPasswordIncorrect;
    @FXML
    public Text txt_startTimes;
    @FXML
    public TextField tb_undoLimit;
    @FXML
    public CheckBox cb_topMost;
    @FXML
    public Text txt_currentPasswordIncorrect;
    @FXML
    public PasswordField pb_currentPassword;
    @FXML
    public CheckBox cb_generateUpperChar;
    @FXML
    public CheckBox cb_generateLowerChar;
    @FXML
    public CheckBox cb_generateSpecialChar;
    @FXML
    public CheckBox cb_generateNumber;
    @FXML
    public CheckBox cb_animatedBackground;
    @FXML
    public VBox vbox_cbs;
    @FXML
    public TextField tb_backgroundOpacity;
    @FXML
    public TextField tb_generateLength;

    public static <T extends Parent> Stage show()
    {
        if (Window != null)
        {
            Window.setAlwaysOnTop(true);
            Window.setAlwaysOnTop(false);
            return Window;
        }
        T root = null;
        try
        {
            root = FXMLLoader.load(SettingsWindow.class.getResource("SettingsWindow.fxml"));
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        var window = new Stage();
        window.setTitle("设置");
        window.setScene(new Scene(root));
        window.getIcons().add(Helper.Icon);
        window.setResizable(false);
        window.setAlwaysOnTop(WindowHelper.MainStage.isAlwaysOnTop());
        window.setOnCloseRequest(e -> {
            Window = null;
        });
        window.addEventHandler(WindowEvent.WINDOW_SHOWN, windowEvent -> {
            window.getScene().getRoot().getChildrenUnmodifiable().get(1).requestFocus();
            {
                var txt = (Text) window.getScene().lookup("#txt_startTimes");
                txt.setText("你已启动PasswordBook " + Helper.StartTimes + "次");
            }
            {
                var tb = (TextField) window.getScene().lookup("#tb_undoLimit");
                tb.setText(String.valueOf(Settings.getUndoLimitForShow()));
            }
            {
                var tb_generateLength = (TextField) window.getScene().lookup("#tb_generateLength");
                tb_generateLength.setText(String.valueOf(Settings.getGenerateLength()));
            }
            {
                var tb_backgroundOpacity = (TextField) window.getScene().lookup("#tb_backgroundOpacity");
                tb_backgroundOpacity.setText(String.valueOf(Settings.getAnimatedBackgroundOpacity()));
            }
        });
        window.sizeToScene();
        window.requestFocus();
        Window = window;
        window.show();
        return window;
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle)
    {
        txt_oldPasswordIncorrect.setVisible(false);

        cb_topMost.setSelected(Settings.getTopMost());
        cb_generateUpperChar.setSelected(Settings.getUseUpperChar());
        cb_generateUpperChar.selectedProperty().addListener((observableValue, oldValue, newValue) -> {
            if (newValue)
            {
                Settings.setUseUpperChar(newValue);
                Settings.saveSettingsFile();
                return;
            }
            for (var cb : vbox_cbs.getChildren())
            {
                if (cb.hashCode() != cb_generateUpperChar.hashCode() && ((CheckBox) cb).isSelected())
                {
                    cb_generateUpperChar.setSelected(newValue);
                    Settings.setUseUpperChar(newValue);
                    Settings.saveSettingsFile();
                    return;
                }
            }
            cb_generateUpperChar.setSelected(oldValue);
        });
        cb_generateLowerChar.setSelected(Settings.getUseLowerChar());
        cb_generateLowerChar.selectedProperty().addListener((observableValue, oldValue, newValue) -> {
            if (newValue)
            {
                Settings.setUseLowerChar(newValue);
                Settings.saveSettingsFile();
                return;
            }
            for (var cb : vbox_cbs.getChildren())
            {
                if (cb.hashCode() != cb_generateLowerChar.hashCode() && ((CheckBox) cb).isSelected())
                {
                    cb_generateLowerChar.setSelected(newValue);
                    Settings.setUseLowerChar(newValue);
                    Settings.saveSettingsFile();
                    return;
                }
            }
            cb_generateLowerChar.setSelected(oldValue);
        });
        cb_generateSpecialChar.setSelected(Settings.getUseSpecialChar());
        cb_generateSpecialChar.selectedProperty().addListener((observableValue, oldValue, newValue) -> {
            if (newValue)
            {
                Settings.setUseSpecialChar(newValue);
                Settings.saveSettingsFile();
                return;
            }
            for (var cb : vbox_cbs.getChildren())
            {
                if (cb.hashCode() != cb_generateSpecialChar.hashCode() && ((CheckBox) cb).isSelected())
                {
                    cb_generateSpecialChar.setSelected(newValue);
                    Settings.setUseSpecialChar(newValue);
                    Settings.saveSettingsFile();
                    return;
                }
            }
            cb_generateSpecialChar.setSelected(oldValue);
        });
        cb_generateNumber.setSelected(Settings.getUseNumber());
        cb_generateNumber.selectedProperty().addListener((observableValue, oldValue, newValue) -> {
            if (newValue)
            {
                Settings.setUseNumber(newValue);
                Settings.saveSettingsFile();
                return;
            }
            for (var cb : vbox_cbs.getChildren())
            {
                if (cb.hashCode() != cb_generateNumber.hashCode() && ((CheckBox) cb).isSelected())
                {
                    cb_generateNumber.setSelected(newValue);
                    Settings.setUseNumber(newValue);
                    Settings.saveSettingsFile();
                    return;
                }
            }
            cb_generateNumber.setSelected(oldValue);
        });

        cb_topMost.selectedProperty().addListener((observableValue, oldValue, newValue) -> {
            WindowHelper.MainStage.setAlwaysOnTop(newValue);
            Settings.setTopMost(newValue);
            Settings.saveSettingsFile();
        });

        cb_animatedBackground.setSelected(Settings.getUseAnimatedBackground());
        cb_animatedBackground.selectedProperty().addListener((observableValue, oldValue, newValue) -> {
            if (!newValue && ((MainWindow) WindowHelper.MainController).getParticleBackground() != null)
            {
                ((MainWindow) WindowHelper.MainController).getParticleBackground().stop();
            }
            else if (newValue && ((MainWindow) WindowHelper.MainController).getParticleBackground() != null)
            {
                ((MainWindow) WindowHelper.MainController).getParticleBackground().start();
            }
            Settings.setUseAnimatedBackground(newValue);
            Settings.saveSettingsFile();
        });
    }

    public void changePasswordOnAction(ActionEvent actionEvent)
    {
        if (StringUtils.isEmpty(tb_newPassword.getText()) && StringUtils.isEmpty(tb_oldPassword.getText()))
        {
            return;
        }
        if (!PasswordBook.checkPassword(tb_oldPassword.getText()))
        {
            txt_oldPasswordIncorrect.setText("旧密码不正确");
            return;
        }
        PasswordBook.changePBKey(tb_newPassword.getText());
        txt_oldPasswordIncorrect.setText("密码修改成功");
        txt_oldPasswordIncorrect.setVisible(true);
    }

    public void backupFileOnAction(ActionEvent actionEvent)
    {
        if (!PasswordBook.checkPassword(pb_currentPassword.getText()))
        {
            txt_currentPasswordIncorrect.setVisible(true);
            return;
        }
        var folder = Helper.selectPasswordBookPath("选择备份文件的储存文件夹");
        if (PasswordBook.backupKey(pb_currentPassword.getText(), PasswordBook.UserName, folder + File.separator + "密码备份.txt"))
        {
            txt_currentPasswordIncorrect.setText("保存成功");
        }
        else
        {
            txt_currentPasswordIncorrect.setText("保存失败");
        }
    }

    public void buSaveUndoLimitOnAction(ActionEvent actionEvent)
    {
        try
        {
            var undoLimit = Integer.parseInt(tb_undoLimit.getText());
            if (undoLimit < 5)
            {
                tb_undoLimit.setText(String.valueOf(5));
                undoLimit = 5;
            }
            else if (undoLimit > 200)
            {
                tb_undoLimit.setText(String.valueOf(200));
                undoLimit = 200;
            }
            Settings.setUndoLimitFromShow(undoLimit);
            Settings.saveSettingsFile();
            OperationManager.reset(Settings.getUndoLimit());
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            tb_undoLimit.setText(String.valueOf(Settings.getUndoLimitForShow()));
        }
    }

    public void buSaveBackgroundOpacity(ActionEvent actionEvent)
    {
        try
        {
            double opacity = Double.parseDouble(tb_backgroundOpacity.getText());
            if (opacity < 0.0)
            {
                tb_backgroundOpacity.setText("0");
                opacity = 0.0;
            }
            else if (opacity > 1.0)
            {
                tb_backgroundOpacity.setText("1");
                opacity = 1.0;
            }

            Settings.setAnimatedBackgroundOpacity(opacity);
            Settings.saveSettingsFile();
            ((MainWindow) WindowHelper.MainController).getParticleCanvas().setOpacity(opacity);
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            tb_backgroundOpacity.setText(String.valueOf(Settings.getAnimatedBackgroundOpacity()));
        }
    }

    public void buSaveGenerateLengthOnAction(ActionEvent actionEvent)
    {
        try
        {
            int length = Integer.parseInt(tb_generateLength.getText());
            if (length < 5)
            {
                tb_generateLength.setText("5");
                length = 5;
            }
            else if (length > 30)
            {
                tb_generateLength.setText("30");
                length = 30;
            }

            Settings.setGenerateLength(length);
            Settings.saveSettingsFile();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            tb_generateLength.setText(String.valueOf(Settings.getGenerateLength()));
        }
    }
}
